//////////////////////////////////////////////////////////////////////
//
//  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//  ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
//  TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//  PARTICULAR PURPOSE.
//
// This code is released under the Microsoft Public License.  Please
// refer to LICENSE.TXT for the full text of the license.
//
// Copyright 2012 Guan-Tik Tiunn.  All rights reserved.
// Portions Copyright 2003 Microsoft Corporation.  All rights reserved.
//
// Adapted from the Text Services Framework Sample Code, available under
// the Microsoft Public License from:
//    http://code.msdn.microsoft.com/tsf
//////////////////////////////////////////////////////////////////////


#include "Globals.h"
#include "EditSession.h"
#include "TextService.h"
//extern int POJ_enable;
//+---------------------------------------------------------------------------
//
// CStartCompositinoEditSession
//
//----------------------------------------------------------------------------

class CStartCompositionEditSession : public CEditSessionBase
{
public:
	CStartCompositionEditSession(CTextService *pTextService, ITfContext *pContext) : CEditSessionBase(pTextService, pContext)
	{
	}

	// ITfEditSession
	STDMETHODIMP DoEditSession(TfEditCookie ec);
};

//+---------------------------------------------------------------------------
//
// DoEditSession
//
//----------------------------------------------------------------------------

STDAPI CStartCompositionEditSession::DoEditSession(TfEditCookie ec)
{
	#ifdef _DEBUG
	DebugPrintf("STDAPI CStartCompositionEditSession::DoEditSession(TfEditCookie ec)");
    #endif
	ITfInsertAtSelection *pInsertAtSelection = NULL;
	ITfRange *pRangeInsert = NULL;
	ITfContextComposition *pContextComposition = NULL;
	ITfComposition *pComposition = NULL;
	HRESULT hr = E_FAIL;



	// A special interface is required to insert text at the selection
	if (_pContext->QueryInterface(IID_ITfInsertAtSelection, (void **)&pInsertAtSelection) != S_OK)
	{
		goto Exit;
	}

	// insert the text
	if (pInsertAtSelection->InsertTextAtSelection(ec, TF_IAS_QUERYONLY, NULL, 0, &pRangeInsert) != S_OK)
	{
		goto Exit;
	}

	// get an interface on the context to deal with compositions
	if (_pContext->QueryInterface(IID_ITfContextComposition, (void **)&pContextComposition) != S_OK)
	{
		goto Exit;
	}

	/*
	ITfMouseTracker *pMouseTracker;

	if (_pContext->QueryInterface(IID_ITfMouseTracker, (LPVOID*)&pMouseTracker)!= S_OK);
	{
		goto Exit;
	}
	pMouseTracker->AdviseMouseSink(pRangeInsert, (ITfMouseSink *)this,pdwCookie);
	*/


	// start the new composition
	if ((pContextComposition->StartComposition(ec, pRangeInsert, _pTextService, &pComposition) == S_OK) && (pComposition != NULL))
	{
		#ifdef _DEBUG
		DebugPrintf("if ((pContextComposition->StartComposition(ec, pRangeInsert, _pTextService, &pComposition) == S_OK) && (pComposition != NULL))");
		#endif
		// Store the pointer of this new composition object in the instance 
		// of the CTextService class. So this instance of the CTextService 
		// class can know now it is in the composition stage.
		_pTextService->_SetComposition(pComposition);

		// 
		//  set selection to the adjusted range
		// 
		TF_SELECTION tfSelection;
		tfSelection.range = pRangeInsert;
		tfSelection.style.ase = TF_AE_NONE;
		tfSelection.style.fInterimChar = FALSE;
		_pContext->SetSelection(ec, 1, &tfSelection);

		
	}

Exit:
	if (pContextComposition != NULL)
		pContextComposition->Release();

	if (pRangeInsert != NULL)
		pRangeInsert->Release();

	if (pInsertAtSelection != NULL)
		pInsertAtSelection->Release();

	return S_OK;
}

//+---------------------------------------------------------------------------
//
// _StartComposition
//
// this starts the new composition at the selection of the current 
// focus context.
//----------------------------------------------------------------------------

void CTextService::_StartComposition(ITfContext *pContext)
{
	#ifdef _DEBUG
	DebugPrintf("void CTextService::_StartComposition(ITfContext *pContext)");
    #endif
	CStartCompositionEditSession *pStartCompositionEditSession;

	if (pStartCompositionEditSession = new CStartCompositionEditSession(this, pContext))
	{
		HRESULT hr;
		// A synchronus document write lock is required.
		// the CStartCompositionEditSession will do all the work when the
		// CStartCompositionEditSession::DoEditSession method is called by the context
		pContext->RequestEditSession(_tfClientId, pStartCompositionEditSession, TF_ES_SYNC | TF_ES_READWRITE, &hr);

		pStartCompositionEditSession->Release();
	}

}
